package com.nekonomics
package api

import api.dto.response.ErrorRsp
import api.route.*
import error.AppError

import zio.http.*
import zio.json.*
import zio.{Cause, ZIO}

/**
 * routes aggregate
 */

def errorHandler(cause: Cause[Any]): ZIO[Any, Nothing, Response] = {

  val trace = cause.prettyPrint
  cause.failures.head match {
    case e: AppError =>
      ZIO.logWarning(s"[AppError] ${e.getMsg}\n$trace") *>
        ZIO.succeed(
          Response.json(ErrorRsp.fromAppError(e).toJson).status(e.httpStatus)
        )

    case e: String => ZIO.logWarning(e) *> ZIO.succeed(
      Response
        .json(ErrorRsp.of(9999, s"[String] $e\n$trace").toJson)
        .status(Status.BadRequest)
    )

    // todo 后期一律只返回状态码
    case e: Throwable =>
      ZIO.logWarning(s"[Throwable] ${e.getMessage}\n$trace") *>
        ZIO.succeed(
          Response.json(ErrorRsp.fromThrowable(e).toJson).status(Status.InternalServerError)
        )

    case a: Any =>
      ZIO.logWarning(s"[Any] ${a.toString}\n$trace") *>
        ZIO.succeed(
          Response.json(ErrorRsp.of(9999, a.toString).toJson).status(Status.InternalServerError)
        )
  }
}


object HttpApp {
  lazy val routes = (
    CartRoute.routes
      ++ OrderRoute.routes
      ++ ProductRoute.routes
      ++ UserRoute.routes
      ++ TestRoute.routes
      ++ PayRoute.routes
      ++ MerchantRoute.routes
    
    )
    .handleErrorCauseZIO(errorHandler)
}
